
/*
 * Hlpay-Plus aggregate payment system. Copyright
 * (c) 2022-2023 Hlpay Team Copyright has the right of final interpretation.
 */
package com.hlkj.pay.app.adminuser.impl;

import com.hlkj.framework.common.util.json.JsonUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.hlkj.framework.caches.service.RedisTemplateService;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.pojo.LocalContext;
import com.hlkj.pay.app.adminuser.IOrganizationAppService;
import com.hlkj.pay.common.AdminUserResultCode;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.common.constants.AdminRedisConstant;
import com.hlkj.pay.enums.AdminUserEnum;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.infrastructure.model.admin.OrganizationDO;
import com.hlkj.pay.service.admin.IOrganizationService;
import com.hlkj.pay.service.common.IBusinessLogService;
import com.hlkj.pay.vo.admin.req.organization.OrganizationReq;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/09/08 11:23
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrganizationAppServiceImpl implements IOrganizationAppService {

    private final IOrganizationService organizationService;
    private final RedisTemplateService redisTemplateService;
    private final IBusinessLogService businessLogService;

    @Override
    public CommonResult<Void> addOrganization(OrganizationReq organizationReq) {
        log.info("addOrganization organizationReq:{}", JsonUtils.toJsonString(organizationReq));
        try {
            OrganizationDO organizationDO = new OrganizationDO();
            BeanUtils.copyProperties(organizationReq, organizationDO);
            if (StringUtils.hasText(organizationReq.getParentOrganizationCode())) {
                String parentOrganizationCode = organizationReq.getParentOrganizationCode();
                OrganizationDO parentOrganizationDO = organizationService
                        .queryOrganizationDetail(parentOrganizationCode);
                if (parentOrganizationDO == null) {
                    return CommonResult.error(AdminUserResultCode.PARENT_ORGANIZATION_DOES_NOT_EXIST);
                }
                organizationDO.setType(parentOrganizationDO.getType() + 1);
            }else {
                organizationDO.setType(AdminUserEnum.ORGANIZATION_TYPE.HEAD_OFFICE.getCode());
            }
            organizationDO.setSn(LocalContext.get().getSn());
            organizationService.addOrganizationDO(organizationDO);
            return CommonResult.success(null);
        } catch (Exception e) {
            log.error("addOrganization error:{}", e.getMessage(),e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }
    @Override
    public CommonResult<Void> updateOrganization(OrganizationReq organizationReq) {
        log.info("updateOrganization organizationReq:{}", JsonUtils.toJsonString(organizationReq));
        try {
            OrganizationDO beforeOrganization = organizationService
                    .queryOrganizationDetail(organizationReq.getOrganizationCode());
            if (beforeOrganization == null) {
                return CommonResult.error(AdminUserResultCode.ORGANIZATION_DOES_NOT_EXIST);
            }
            OrganizationDO afterOrganization = new OrganizationDO();
            BeanUtils.copyProperties(organizationReq, afterOrganization);
            //重新计算系统父组织编码和系统组织编码
            OrganizationDO parentOrganizationDO=null;
            if (StringUtils.hasText(organizationReq.getParentOrganizationCode())) {
                String parentOrganizationCode = organizationReq.getParentOrganizationCode();
                parentOrganizationDO = organizationService
                        .queryOrganizationDetail(parentOrganizationCode);
                if (parentOrganizationDO == null) {
                    return CommonResult.error(AdminUserResultCode.PARENT_ORGANIZATION_DOES_NOT_EXIST);
                }
                afterOrganization.setType(parentOrganizationDO.getType() + 1);
            } else {
                //之前类型不是总部的 ，不能改成总部 及 parentOrganizationCode 不能是0 0 是总部的父组织编码
                afterOrganization.setParentOrganizationCode(null);
            }
            afterOrganization.setId(beforeOrganization.getId());
            afterOrganization.setUpdateTime(null);

            //更新数据库
            organizationService.updateOrganizationDO(afterOrganization,beforeOrganization.getParentOrganizationCode());
            //清理缓存
            clearCacheData(afterOrganization.getOrganizationCode());
            businessChangeLog(beforeOrganization, afterOrganization);
            return CommonResult.success(null);
        } catch (Exception e) {
            log.error("userDetail error:{}", e.getMessage(),e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }
    @Override
    public CommonResult<Void> delOrganization(String organizationCode) {
        log.info("organizationCode organizationCode:{}", organizationCode);
        try {
            OrganizationDO beforeOrganization = organizationService
                    .queryOrganizationDetail(organizationCode);
            if (beforeOrganization == null) {
                return CommonResult.error(AdminUserResultCode.ORGANIZATION_DOES_NOT_EXIST);
            }
            //更新数据库
            organizationService.delOrganizationDO(beforeOrganization.getId());
            //清理缓存
            clearCacheData(organizationCode);
            //变更日志
            OrganizationDO afterOrganization = BeanUtil.copyProperties(beforeOrganization, OrganizationDO.class);
            afterOrganization.setDeleteFlag(Boolean.TRUE);
            businessChangeLog(beforeOrganization, afterOrganization);
            return CommonResult.success(null);
        } catch (Exception e) {
            log.error("userDetail error:{}", e.getMessage(),e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }
    
    private void clearCacheData(String organizationCode) {
        String redisKey = organizationDataRedisKey(organizationCode);
        //清理缓存操作
        if (redisTemplateService.hasKey(redisKey)) {
            redisTemplateService.del(redisKey);
        }
    }

    /**
     * 组织详情 缓存key
     *
     * @param organizationCode 字典编码
     * @return key
     */
    private String organizationDataRedisKey(String organizationCode) {
        return StrUtil.builder().append(AdminRedisConstant.ORGANIZATION_DETAILS_KEY)
                .append(organizationCode).toString();
    }

    /**
     * log object
     *
     * @param beforeOrganization
     * @param afterOrganization
     * @return
     */
    void businessChangeLog(OrganizationDO beforeOrganization, OrganizationDO afterOrganization) {
        businessLogService.addBusinessChangeLog(beforeOrganization.getOrganizationCode(),
                AdminUserEnum.CHANGE_LOG_TYPE.ORGANIZATION.getCode(),
                CommonEnum.CHANGE_LOG_MODEL_TYPE.ADMIN,
                beforeOrganization,
                afterOrganization);
    }
    
}
